﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Civilisation_code.PCarte;
using Civilisation_code.PInterfaces_Fabrique_Unite;
using Civilisation_code.Implementation_Unite_INFO;
using Civilisation_code.Implementation_Unite_EII;
using System.Windows.Media;
using Civilisation_code.PPartie;
using System.Runtime.Serialization;

namespace Civilisation_code.PJoueur
{
    /// <summary>
    /// Classe Joueur regroupant toutes les informations d'un joueur : ses unités, ses villes, son nom, etc.
    /// </summary>
    [Serializable]
    public class Joueur : ISerializable
    {
        /// <summary>
        /// Nom de la civilisation du joueur
        /// </summary>
        public string _civilisation { set; get; }

        /// <summary>
        /// Pseudo du joueur
        /// </summary>
        public string _nom { set; get; }

        /// <summary>
        /// Couleur associée au joueur
        /// </summary>
        [field: NonSerializedAttribute()] 
        private SolidColorBrush _color;
        public SolidColorBrush Color 
        { 
            set
            {
                _color = value;   
            }

            get
            {
                return _color;
            }   
        }

        /// <summary>
        /// Unités du joueur
        /// </summary>
        public List<Unite> _unites { set; get; }

        /// <summary>
        /// Villes du joueur
        /// </summary>
        public List<Ville> _villes { set; get; }

        /// <summary>
        /// Fabrique associée à la civilisation du joueur
        /// </summary>
        public Fabrique_Unite _fabrique { set; get; }


        public Partie _partie 
        {
            get;
            set;
        }

        /// <summary>
        /// Constructeur d'une instance de Joueur
        /// </summary>
        /// <param name="nom">Nom du joueur</param>
        /// <param name="civilisation">Nom de la civilisation (INFO ou EII)</param>
        /// <param name="color">Couleur associée au joueur</param>
        /// <param name="c">Case de départ du joueur</param>
        public Joueur(string nom, string civilisation,Color color ,Case c, Partie p)
        {
            //Initialisation des attributs
            Color = new SolidColorBrush(color);
            _nom = nom;
            _civilisation = civilisation;
            _unites = new List<Unite>();
            _villes = new List<Ville>();
            _partie = p;

            if (civilisation.Equals("INFO"))
                _fabrique = Fabrique_Unite_INFO.FABRIQUE_UNITE;
            else
                _fabrique = Fabrique_Unite_EII.FABRIQUE_UNITE;

            _fabrique.creerEtudiant(c,this);
            _fabrique.creerEnseignant(c,this);

        }

        /// <summary>
        /// Permet d'effectuer tout le travail nécessaire au début du tour
        /// </summary>
        public void nouveauTour()
        {
            foreach(Ville ville in _villes)
            {
                ville.nouveauTour();
            }
            foreach (Unite unite in _unites)
            {
                unite.nouveauTour();
            }
            vueSur();

        }

        /// <summary>
        /// Liste des cases où le joueur peut visualiser les unités placer dessus
        /// </summary>
        /// <returns></returns>
        public void vueSur()
        {
            List<Case> l = new List<Case>();
            List<Case> tmp = new List<Case>();

            //On récupère toutes les cases qui sont visibles par nos unités
            foreach (Unite u in _unites)
            {
                tmp = u.vueSur();
                foreach (Case c in tmp)
                {
                    //Si la case n'est pas déjà présente dans la liste, on l'ajoute
                    if (!l.Contains(c))
                        l.Add(c);
                }
            }
            //On récupère toutes les cases qui sont visibles par nos villes
            foreach (Ville v in _villes)
            {
                tmp = v.vueSur();
                foreach (Case c in tmp)
                {
                    //Si la case n'est pas déjà présente dans la liste, on l'ajoute
                    if (!l.Contains(c))
                        l.Add(c);
                }
            }

            bool y = false;
            
            foreach(Case c in _partie._carte._cases.Values){
                y = l.Contains(c);

                if (y && c.Brouillard != false)
                {
                    c.Brouillard = false;
                }
                else if (!y && c.Brouillard != true)
                {
                    c.Brouillard = true;
                }
            }
        }
        /// <summary>
        /// Permet de savoir si le joueur a un directeur en vie
        /// </summary>
        /// <returns>Vrai si le joueur possède un directeut en vie
        ///          Faux sinon</returns>
        public bool possedeDirecteur()
        {
            foreach(Unite u in _unites){
                if (u is Directeur)
                    return true;
            }
            return false;
        }

        /// <summary>
        /// Méthode de sérialization
        /// </summary>
        /// <param name="info"></param>
        /// <param name="context"></param>
        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("_civilisation", this._civilisation);
            info.AddValue("_nom", this._nom);
            info.AddValue("_color_a", this._color.Color.A);
            info.AddValue("_color_b", this._color.Color.B);
            info.AddValue("_color_r", this._color.Color.R);
            info.AddValue("_color_g", this._color.Color.G);
            info.AddValue("_unites", this._unites);
            info.AddValue("_villes", this._villes);
            info.AddValue("_fabrique", this._fabrique);
            info.AddValue("_partie", this._partie);
        }
        /// <summary>
        /// Constructeur
        /// </summary>
        /// <param name="info"></param>
        /// <param name="context"></param>
        Joueur(SerializationInfo info,StreamingContext context)
        {
            this._civilisation = info.GetString("_civilisation");
            this._nom = info.GetString("_nom");
            Byte a = info.GetByte("_color_a");
            Byte b = info.GetByte("_color_b");
            Byte r = info.GetByte("_color_r");
            Byte g = info.GetByte("_color_g");
            this._color = new SolidColorBrush();
            Color c = new Color();
            c.A = a;
            c.B = b;
            c.R = r;
            c.G = g;
            this._color.Color = c;
            this._unites = (List<Unite>)info.GetValue("_unites", typeof(List<Unite>));
            this._villes = (List<Ville>)info.GetValue("_villes", typeof(List<Ville>));
            this._fabrique = (Fabrique_Unite)info.GetValue("_fabrique", typeof(Fabrique_Unite));
            this._partie = (Partie)info.GetValue("_partie", typeof(Partie));
        }

    }
}
